#include "pch.h"
#include "OpusEncoder.h"

OpusEncode::OpusEncode(int sampleRate, int channels, int bitrate, AudioEncDataObserver* p)
    : sampleRate_(sampleRate), channels_(channels), bitrate_(bitrate), ob_(p) {
    int error;

    // Create an Opus encoder
    encoder_ = opus_encoder_create(sampleRate_, channels_, OPUS_APPLICATION_AUDIO, &error);
    if (error != OPUS_OK) {
        log_error( "Failed to create Opus encoder: %s\n", opus_strerror(error));
        encoder_ = nullptr;
        return;
    }

    // Set bitrate
    if (opus_encoder_ctl(encoder_, OPUS_SET_BITRATE(bitrate_*1000)) != OPUS_OK) {
        log_error( "Failed to set bitrate\n");
    }

    packet_len_ = 2000;
    packet_buffer_ = std::make_unique<char[]>(packet_len_);
    memset(packet_buffer_.get(), 0, packet_len_);
}

OpusEncode::~OpusEncode() {
    if (encoder_) {
        opus_encoder_destroy(encoder_);
    }
}

void OpusEncode::encode(void* data, size_t dataSize, long long pts) {
    if (!encoder_) {
        log_error( "Encoder is not initialized\n");
        return;
    }

    int result = opus_encode(encoder_, (const opus_int16*)data, dataSize/2/channels_,
        (unsigned char*)packet_buffer_.get(), packet_len_);

    if (result < 0) {
        log_error( "Encoding failed: %s\n", opus_strerror(result));
        return ;
    }
    if (ob_)
    {
        ob_->onAudioEncodeData(packet_buffer_.get(), result);
    }
}

